package com.hsd.service.impl;

import com.hsd.dao.ISchemaInfoDao;
import com.hsd.dao.ISchemaInfoSqliteDao;
import com.hsd.dto.SchemaConf;
import com.hsd.dto.SchemaInfo;
import com.hsd.framework.util.BeetlUtils;
import com.hsd.framework.util.DateUtil;
import com.hsd.framework.util.StrUtil;
import com.hsd.service.ISchemaInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class SchemaInfoService implements ISchemaInfoService {
    @Autowired
    private ISchemaInfoDao schemaInfoDao;
    @Autowired
    private ISchemaInfoSqliteDao schemaInfoSqliteDao;
    @Value("${spring.datasource.url}")
    private  String dbType;
    @Override
    public List<SchemaInfo> findDbIsList(SchemaInfo dto) throws Exception {
        List<SchemaInfo> beans = null;
        try {
            if(dbType.indexOf("sqlite")!=-1){
                beans = (List<SchemaInfo>) schemaInfoSqliteDao.findDbIsList(dto);
            }else{
                beans = (List<SchemaInfo>) schemaInfoDao.findDbIsList(dto);
            }
        } catch (Exception e) {
            log.error("库列表获取失败!", e);
        }
        return beans;
    }
    @Override
    public List<SchemaInfo> findTableIsList(SchemaInfo dto) throws Exception {
        List<SchemaInfo> beans = null;
        try {
            if(dbType.indexOf("sqlite")!=-1){
                beans = (List<SchemaInfo>) schemaInfoSqliteDao.findTableIsList(dto);
            }else{
                beans = (List<SchemaInfo>) schemaInfoDao.findTableIsList(dto);
            }
        } catch (Exception e) {
            log.error("表列表获取失败!", e);
        }
        return beans;
    }

    @Override
    public List<SchemaInfo> findColumnIsList(SchemaInfo dto) throws Exception {
        List<SchemaInfo> beans = null;
        try {
            if(dbType.indexOf("sqlite")!=-1){
                beans = (List<SchemaInfo>) schemaInfoSqliteDao.findColumnIsList(dto);
            }else{
                beans = (List<SchemaInfo>) schemaInfoDao.findColumnIsList(dto);
            }
        } catch (Exception e) {
            log.error("字段列表获取失败!", e);
        }
        return beans;
    }

    @Override
    public String templateRender(SchemaInfo dto) throws Exception {
        String msg = "success";
        String srcDir = "d:/schema_make_file/src/main/java/";
        String resouseDir = "d:/schema_make_file/src/main/resources/";
        final int[] menunum = {0,0,0};//总,ng,btl
        final int[] sqlnum = { 0 };
        //1.遍历表配置集合
        //2.获取表字段详情
        //3.获取生成配置
        dto.getTablesConf().forEach(tableConf -> {
            try {
                Map context = new HashMap();
                HashMap dtoMap = new HashMap();
                dtoMap.put("db", tableConf.getDbName());
                dtoMap.put("table", tableConf.getTableName());
                SchemaInfo tableObj = null;
                if(dbType.indexOf("sqlite")!=-1){
                    tableObj = (SchemaInfo) schemaInfoSqliteDao.findTableByMap(dtoMap);
                }else{
                    tableObj = (SchemaInfo) schemaInfoDao.findTableByMap(dtoMap);
                }
                tableConf.setTableComment(tableObj.getTableComment());
                SchemaConf schemaConf = tableConf.getSchemaConf();

                context.put("tcfgs", dto.getTablesConf());

                context.put("year", DateUtil.getCurDateStr("yyyy"));
                context.put("date", DateUtil.getCurDateStr("yyyy-MM-dd"));

                List<SchemaInfo> columns =null;
                List<SchemaInfo> pkcolumns=null;
                if(dbType.indexOf("sqlite")!=-1){
                    columns=(List<SchemaInfo>) schemaInfoSqliteDao.findColumnIsListByMap(dtoMap);
                    pkcolumns = (List<SchemaInfo>) schemaInfoSqliteDao.findColumnPkByMap(dtoMap);
                }else{
                    columns=(List<SchemaInfo>) schemaInfoDao.findColumnIsListByMap(dtoMap);
                    pkcolumns = (List<SchemaInfo>) schemaInfoDao.findColumnPkByMap(dtoMap);
                }
                if(pkcolumns!=null && dbType.indexOf("sqlite")!=-1){
                    Iterator<SchemaInfo> it = pkcolumns.iterator();
                    while(it.hasNext()){
                        SchemaInfo pkobj = it.next();
                        if(pkobj.getPk()==null||!pkobj.getPk().equalsIgnoreCase("PRI")){
                            it.remove();
                        }
                    }
                }
                if(pkcolumns!=null && pkcolumns.size()>0){
                    Map<String,String> pkMap=new HashMap<>();
                    pkcolumns.forEach(pk->{
                        pkMap.put(pk.getColumnName(),"1");
                    });
                    context.put("pkMap", pkMap);
                }
                Map<String,String> columnMap=new HashMap<>();
                if(columns!=null && columns.size()>0){
                    columns.forEach(column->{
                        columnMap.put(column.getColumnNameFormat(),column.getJavaType());
                    });
                }
                context.put("columnMap", columnMap);
                context.put("columns", columns);
                context.put("pks", pkcolumns);
                context.put("tcfg", tableConf);//tableConf
                context.put("scfg", schemaConf);//schemaConf
                context.put("tableNameL", StrUtil.toLowerCaseFirstOne(tableConf.getTableNameFormat()));
                context.put("beanVo", columns);//schemaInfoDao.findSpringVO(dtoMap));
                context.put("xmlInsert", columns);// schemaInfoDao.findMybatisInsert(dtoMap));
                context.put("xmlSelect", columns);// schemaInfoDao.findMybatisSelect(dtoMap));
                context.put("xmlUpdate", columns);// schemaInfoDao.findMybatisUpdate(dtoMap));
                context.put("pageTag", "#pageTag");// btl分页标签
                //4.生成
                String verDir = schemaConf.get_template_dir();
                switch (schemaConf.get_template_dir()){
                    case "fxml":{
                        //domain
                        if ("1".equals(tableConf.getSchemaConf().get_domain())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/Demo.java", context, srcDir + StrUtil.getDir(schemaConf.get_domain_pkg()) + "/" + tableConf.getTableNameFormat() + ".java");
                        }
                        //dto
                        if ("1".equals(tableConf.getSchemaConf().get_dto())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/DemoDto.java", context, srcDir + StrUtil.getDir(schemaConf.get_dto_pkg()) + "/" + tableConf.getTableNameFormat() + "Dto.java");
                        }
                        //mybatis
                        if ("1".equals(tableConf.getSchemaConf().get_mybatis())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/view/Demo.xml", context, resouseDir + StrUtil.getDir(schemaConf.get_mybatis_pkg()) + "/" + StrUtil.toLowerCaseFirstOne(tableConf.getTableNameFormat()) + ".xml");
                        }
                        //dao
                        if ("1".equals(tableConf.getSchemaConf().get_dao())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/IDemoDao.java", context, srcDir + StrUtil.getDir(schemaConf.get_dao_pkg()) + "/" + "I" + tableConf.getTableNameFormat() + schemaConf.get_dao_suffix()+".java");
                        }
                        //service
                        if ("1".equals(tableConf.getSchemaConf().get_biz())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/DemoService.java", context, srcDir + StrUtil.getDir(schemaConf.get_biz_pkg()) + "/" + tableConf.getTableNameFormat() + "Service.java");
                        }
                        //api
                        if ("1".equals(tableConf.getSchemaConf().get_api())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/IDemoService.java", context, srcDir + StrUtil.getDir(schemaConf.get_api_pkg()) + "/" + "I" + tableConf.getTableNameFormat() + "Service.java");
                        }
                        if ("1".equals(tableConf.getSchemaConf().get_web_rest())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/FXMLController.java", context, srcDir + StrUtil.getDir(schemaConf.get_web_pkg()) + "/" + tableConf.getTableNameFormat() + "Controller.java");
                        }
                        if ("1".equals(tableConf.getSchemaConf().get_view_btl())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/view/FXMLView.fxml", context, resouseDir + StrUtil.getDir(schemaConf.get_fxml_ui_pkg()) + "/" + StrUtil.toLowerCaseFirstOne(tableConf.getTableNameFormat()) + ".fxml");
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/FXMLView.java", context, srcDir + StrUtil.getDir(schemaConf.get_fxml_java_pkg()) + "/" + tableConf.getTableNameFormat() + "View.java");

                            if ("1".equals(tableConf.getSchemaConf().get_detail())) {
                                BeetlUtils.renderToFile("/btl/" + verDir + "/view/FXMLViewInfo.fxml", context, resouseDir + StrUtil.getDir(schemaConf.get_fxml_ui_pkg()) + "/" + StrUtil.toLowerCaseFirstOne(tableConf.getTableNameFormat()) + "Info.fxml");
                                BeetlUtils.renderToFile("/btl/" + verDir + "/java/FXMLViewInfo.java", context, srcDir + StrUtil.getDir(schemaConf.get_fxml_java_pkg()) + "/" + tableConf.getTableNameFormat() + "InfoView.java");
                            }

                            if ("1".equals(tableConf.getSchemaConf().get_insert())||"1".equals(tableConf.getSchemaConf().get_update())) {
                                BeetlUtils.renderToFile("/btl/" + verDir + "/view/FXMLViewEdit.fxml", context, resouseDir + StrUtil.getDir(schemaConf.get_fxml_ui_pkg()) + "/" + StrUtil.toLowerCaseFirstOne(tableConf.getTableNameFormat()) + "Edit.fxml");
                                BeetlUtils.renderToFile("/btl/" + verDir + "/java/FXMLViewEdit.java", context, srcDir + StrUtil.getDir(schemaConf.get_fxml_java_pkg()) + "/" + tableConf.getTableNameFormat() + "EditView.java");
                            }
                        }
                        break;
                    }
                    default:{
                        //domain
                        if ("1".equals(tableConf.getSchemaConf().get_domain())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/Demo.java", context, srcDir + StrUtil.getDir(schemaConf.get_domain_pkg()) + "/" + tableConf.getTableNameFormat() + ".java");
                        }
                        //dto
                        if ("1".equals(tableConf.getSchemaConf().get_dto())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/DemoDto.java", context, srcDir + StrUtil.getDir(schemaConf.get_dto_pkg()) + "/" + tableConf.getTableNameFormat() + "Dto.java");
                        }
                        //mybatis
                        if ("1".equals(tableConf.getSchemaConf().get_mybatis())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/Demo.xml", context, resouseDir + StrUtil.getDir(schemaConf.get_mybatis_pkg()) + "/" + StrUtil.toLowerCaseFirstOne(tableConf.getTableNameFormat()) + ".xml");
                        }
                        //dao
                        if ("1".equals(tableConf.getSchemaConf().get_dao())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/IDemoDao.java", context, srcDir + StrUtil.getDir(schemaConf.get_dao_pkg()) + "/" + "I" + tableConf.getTableNameFormat() + schemaConf.get_dao_suffix()+".java");
                        }
                        //service
                        if ("1".equals(tableConf.getSchemaConf().get_biz())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/DemoService.java", context, srcDir + StrUtil.getDir(schemaConf.get_biz_pkg()) + "/" + tableConf.getTableNameFormat() + "Service.java");
                        }
                        //api
                        if ("1".equals(tableConf.getSchemaConf().get_api())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/IDemoService.java", context, srcDir + StrUtil.getDir(schemaConf.get_api_pkg()) + "/" + "I" + tableConf.getTableNameFormat() + "Service.java");

                            if(dbType.indexOf("sqlite")==-1){
                                BeetlUtils.renderToFile("/btl/" + verDir + "/java/DemoFallback.java", context, srcDir + StrUtil.getDir(schemaConf.get_fallback_pkg()) + "/" + "" + tableConf.getTableNameFormat() + "Fallback.java");
                            }
                        }
                        //web.rest
                        if ("1".equals(tableConf.getSchemaConf().get_web_rest())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/RestDemoController.java", context, srcDir + StrUtil.getDir(schemaConf.get_web_pkg()) + "/" + tableConf.getTableNameFormat() + "Controller.java");
                        }
                        //web.ctrl
                        if ("1".equals(tableConf.getSchemaConf().get_web_ctrl())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/WebDemoController.java", context, srcDir + StrUtil.getDir(schemaConf.get_web_pkg()) + "/" + tableConf.getTableNameFormat() + "Controller.java");
                        }
                        //view.ng
                        if ("1".equals(tableConf.getSchemaConf().get_view_ng())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/view/ng/init.html", context, resouseDir + "html/" + StrUtil.getDir(schemaConf.get_view_pkg()) + "/" + tableConf.getTableName() + ".vue");
                            if ("1".equals(tableConf.getSchemaConf().get_insert()) || "1".equals(tableConf.getSchemaConf().get_update())) {
                                BeetlUtils.renderToFile("/btl/" + verDir + "/view/ng/edit.html", context, resouseDir + "html/" + StrUtil.getDir(schemaConf.get_view_pkg()) + "/" + tableConf.getTableName() + "_edit.vue");
                            }
                            if ("1".equals(tableConf.getSchemaConf().get_page())) {
                                BeetlUtils.renderToFile("/btl/" + verDir + "/view/ng/info.html", context, resouseDir + "html/" + StrUtil.getDir(schemaConf.get_view_pkg()) + "/" + tableConf.getTableName() + "_info.vue");
                            }
                            ++menunum[1];
                        }

                        //view.btl
                        if ("1".equals(tableConf.getSchemaConf().get_view_btl())) {
                            BeetlUtils.renderToFile("/btl/" + verDir + "/view/btl/init.html", context, resouseDir +"/template/"+ StrUtil.getDir(schemaConf.get_view_pkg()) + "/" + tableConf.getTableName() + ".html");
                            if ("1".equals(tableConf.getSchemaConf().get_insert()) || "1".equals(tableConf.getSchemaConf().get_update())) {
                                BeetlUtils.renderToFile("/btl/" + verDir + "/view/btl/edit.html", context, resouseDir +"/template/"+ StrUtil.getDir(schemaConf.get_view_pkg()) + "/" + tableConf.getTableName() + "_edit.html");
                            }
                            if ("1".equals(tableConf.getSchemaConf().get_page())) {
                                BeetlUtils.renderToFile("/btl/" + verDir + "/view/btl/list.html", context, resouseDir +"/template/"+ StrUtil.getDir(schemaConf.get_view_pkg()) + "/" + tableConf.getTableName() + "_list.html");
                            }
                            ++menunum[2];
                        }
                        //auth.sql
                        if(++sqlnum[0]==dto.getTablesConf().size())
                            BeetlUtils.renderToFile("/btl/" + verDir + "/java/auth.sql", context, resouseDir+"/"+ schemaConf.get_my_pkg()+"_auth.sql");
                        if(++menunum[0]==dto.getTablesConf().size()){
                            if(menunum[1]>0){
                                BeetlUtils.renderToFile("/btl/" + verDir + "/view/ng/menu.html", context, resouseDir+"/"+ schemaConf.get_my_pkg()+".ngmenu.html");
                            }
                            if(menunum[2]>0) {
                                BeetlUtils.renderToFile("/btl/" + verDir + "/view/btl/menu.html", context, resouseDir + "/" + schemaConf.get_my_pkg() + ".btlmenu.html");
                            }
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return msg;
    }
}

